﻿using System;
using System.IO;
using System.Net;
using System.Threading.Tasks;
using Framework.Extensions;

namespace WebCrawler
{
    public interface IHttpClient
    {
        Task<PageInfo> LoadPageInfoAsync(string url);
    }

    public class HttpClient : IHttpClient
    {
        private IContentTypeManager _contentTypeManager;

        public HttpClient(IContentTypeManager contentTypeManager)
        {
            _contentTypeManager = contentTypeManager;
        }

        public int Timeout { get; set; }

        private static Task<WebResponse> GetResponseAsync(WebRequest webRequest)
        {
            if (webRequest == null) throw new ArgumentNullException("webRequest");
            return Task<WebResponse>.Factory.FromAsync(
                webRequest.BeginGetResponse, webRequest.EndGetResponse, webRequest /* object state for debugging */);
        }

        public Task<PageInfo> LoadPageInfoAsync(string url)
        {
            try
            {
                var request = WebRequest.Create(url);
                request.Timeout = this.Timeout * 1000;
                var res = GetResponseAsync(request)
                    .ThenUsing(response => 
                    {
                        if (_contentTypeManager.CanHaveUrls(response.ContentType))
                        {
                            using (var stream = response.GetResponseStream())
                            using (var reader = new StreamReader(stream))
                            {
                                var text = reader.ReadToEnd();
                                return PageInfo.Success(url, text);
                            }
                        }
                        else
                        {
                            return PageInfo.Skip(url);
                        }
                    }, 
                    ex => PageInfo.Error(url, ex));
                return res;
            }
            catch(Exception ex)
            {
                var res = PageInfo.Error(url, ex);
                return Task.Factory.StartNew(() => res);
            }
        }
    }
}